<!DOCTYPE html>
<html>
<head>
<title>Fig 1.50 - Electric Dipoles</title>
</head>
<body>
<canvas id="physicsCanvas" width="650" height="450" style="border:1px solid #000;"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // --- Helper Functions ---

    /**
     * Draws an arrow for an axis (thin line, open arrowhead).
     * This function adds to the current path, so it should be wrapped in beginPath() and stroke().
     * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
     * @param {number} fromx - Starting x-coordinate.
     * @param {number} fromy - Starting y-coordinate.
     * @param {number} tox - Ending x-coordinate.
     * @param {number} toy - Ending y-coordinate.
     * @param {number} headlen - Length of the arrowhead sides.
     */
    function drawAxisArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
    }

    /**
     * Draws a thick arrow with a filled head, used for vectors like dipole moments.
     * This function draws immediately and manages its own state.
     * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
     * @param {number} fromx - Starting x-coordinate.
     * @param {number} fromy - Starting y-coordinate.
     * @param {number} tox - Ending x-coordinate.
     * @param {number} toy - Ending y-coordinate.
     * @param {number} headlen - Length of the arrowhead sides.
     * @param {number} lineWidth - The width of the arrow's line.
     */
    function drawVectorArrow(ctx, fromx, fromy, tox, toy, headlen = 10, lineWidth = 3) {
        ctx.save();
        ctx.lineWidth = lineWidth;
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';

        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);

        // Line
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();

        // Filled Head
        ctx.beginPath();
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.closePath();
        ctx.fill();

        ctx.restore();
    }

    /**
     * Draws text with a subscript (e.g., P₁).
     * @param {CanvasRenderingContext2D} ctx - The canvas rendering context.
     * @param {string} text - The main text.
     * @param {string} sub - The subscript text.
     * @param {number} x - The x-coordinate for the text.
     * @param {number} y - The y-coordinate for the text.
     */
    function drawTextWithSubscript(ctx, text, sub, x, y) {
        const mainFontSize = 20;
        const subFontSize = 14;
        
        ctx.save();
        ctx.textAlign = 'left';
        ctx.textBaseline = 'middle';
        
        // Draw main text
        ctx.font = `${mainFontSize}px Times New Roman`;
        ctx.fillText(text, x, y);
        const textMetrics = ctx.measureText(text);
        
        // Draw subscript
        ctx.font = `${subFontSize}px Times New Roman`;
        ctx.fillText(sub, x + textMetrics.width - 2, y + 6);
        
        ctx.restore();
    }

    // --- Draw Figure (a) ---
    function drawFigureA(offsetX, offsetY) {
        const originX = offsetX;
        const originY = offsetY;
        const zAxisLen = 220;
        const yAxisLen = 150;
        const xAxisDiag = 60;

        // Draw axes
        ctx.lineWidth = 2;
        ctx.beginPath();
        drawAxisArrow(ctx, originX, originY, originX, originY - zAxisLen); // z-axis
        drawAxisArrow(ctx, originX, originY, originX + yAxisLen, originY); // y-axis
        drawAxisArrow(ctx, originX, originY, originX - xAxisDiag * Math.cos(Math.PI/4), originY + xAxisDiag * Math.sin(Math.PI/4)); // x-axis
        ctx.stroke();
        
        // Axis labels
        ctx.font = 'italic 20px Times New Roman';
        ctx.fillText('z', originX, originY - zAxisLen - 12);
        ctx.fillText('y', originX + yAxisLen + 15, originY);
        ctx.fillText('x', originX - xAxisDiag * Math.cos(Math.PI/4) - 10, originY + xAxisDiag * Math.sin(Math.PI/4) + 10);

        // Draw Dipoles P1 and P2
        const p_len = 30;
        const r_dist = 130;
        
        // P1 at origin
        drawVectorArrow(ctx, originX, originY, originX, originY - p_len);
        drawTextWithSubscript(ctx, 'P', '1', originX + 12, originY - p_len);

        // P2 at z=r
        const p2_y = originY - r_dist;
        drawVectorArrow(ctx, originX, p2_y, originX, p2_y - p_len);
        drawTextWithSubscript(ctx, 'P', '2', originX + 12, p2_y);

        // Draw distance 'r'
        const r_line_x = originX - 40;
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        ctx.moveTo(r_line_x, originY);
        ctx.lineTo(r_line_x, p2_y);
        // Ticks
        ctx.moveTo(r_line_x - 5, originY);
        ctx.lineTo(r_line_x + 5, originY);
        ctx.moveTo(r_line_x - 5, p2_y);
        ctx.lineTo(r_line_x + 5, p2_y);
        ctx.stroke();
        ctx.font = 'italic 20px Times New Roman';
        ctx.fillText('r', r_line_x - 15, originY - r_dist / 2);
        
        // Label (a)
        ctx.font = '20px Times New Roman';
        ctx.fillText('(a)', originX, originY + 70);
    }
    
    // --- Draw Figure (b) ---
    function drawFigureB(offsetX, offsetY) {
        const originX = offsetX;
        const originY = offsetY;
        const zAxisLen = 220;
        const yAxisLen = 170;
        const xAxisDiag = 60;

        // Draw axes
        ctx.lineWidth = 2;
        ctx.beginPath();
        drawAxisArrow(ctx, originX, originY, originX, originY - zAxisLen); // z-axis
        drawAxisArrow(ctx, originX, originY, originX + yAxisLen, originY); // y-axis
        drawAxisArrow(ctx, originX, originY, originX - xAxisDiag * Math.cos(Math.PI/4), originY + xAxisDiag * Math.sin(Math.PI/4)); // x-axis
        ctx.stroke();
        
        // Axis labels
        ctx.font = 'italic 20px Times New Roman';
        ctx.fillText('z', originX, originY - zAxisLen - 12);
        ctx.fillText('y', originX + yAxisLen + 15, originY);
        ctx.fillText('x', originX - xAxisDiag * Math.cos(Math.PI/4) - 10, originY + xAxisDiag * Math.sin(Math.PI/4) + 10);

        // Draw Dipoles P1 and P2
        const p_len = 30;
        const r_dist = 140;
        
        // P1 at origin
        drawVectorArrow(ctx, originX, originY, originX, originY - p_len);
        drawTextWithSubscript(ctx, 'P', '1', originX + 12, originY - p_len + 5);

        // P2 at y=r
        const p2_x = originX + r_dist;
        drawVectorArrow(ctx, p2_x, originY, p2_x, originY - p_len);
        drawTextWithSubscript(ctx, 'P', '2', p2_x + 8, originY - p_len + 5);

        // Draw distance 'r'
        const r_line_y = originY + 40;
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        ctx.moveTo(originX, r_line_y);
        ctx.lineTo(p2_x, r_line_y);
        // Ticks
        ctx.moveTo(originX, r_line_y - 5);
        ctx.lineTo(originX, r_line_y + 5);
        ctx.moveTo(p2_x, r_line_y - 5);
        ctx.lineTo(p2_x, r_line_y + 5);
        ctx.stroke();
        ctx.font = 'italic 20px Times New Roman';
        ctx.fillText('r', originX + r_dist / 2, r_line_y + 20);

        // Label (b)
        ctx.font = '20px Times New Roman';
        ctx.fillText('(b)', originX, originY + 70);
    }

    // --- Main Drawing ---
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    drawFigureA(160, 320);
    drawFigureB(470, 320);

    // Draw main figure label
    ctx.font = '20px Times New Roman';
    ctx.fillText('Fig. 1.50', 325, 420);

</script>
</body>
</html>